/**
 * 
 */
package com.thor.palmmall.impl.pay;

import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.thor.commons.exception.ThorServiceException;
import com.thor.commons.util.Assert;
import com.thor.commons.util.JsonUtil;
import com.thor.palmmall.api.elecharges.EleChargesBill;
import com.thor.palmmall.api.elecharges.EleChargesBillState;
import com.thor.palmmall.api.pay.alipay.AliPayConfig;
import com.thor.palmmall.api.pay.alipay.AlipayService;
import com.thor.palmmall.dao.elecharges.EleChargesBillDao;
import com.thor.palmmall.dao.elecharges.PEleChargesBill;
import com.thor.palmmall.dao.elecharges.converter.EleChargesBillConverter;
import com.thor.palmmall.rest.user.AChannelContents;
import com.thor.palmmall.util.pay.tool;

/**
 * @author NuoSa
 *
 * @since 1.0
 */
public class AlipayServiceImpl implements AlipayService {

  private Logger logger = LoggerFactory.getLogger(AlipayServiceImpl.class);
  private final String NOTIFY_FLAG_SUCCESS = "success";
  private final String NOTIFY_FLAG_FAILED = "failed";

  @Autowired
  private AliPayConfig alipayConfig;
  @Autowired
  private EleChargesBillDao eleChargesBillDao;

  @Override
  public String getTradePayRequest(Map<String, String> sParaTemp) throws ThorServiceException {
    Assert.assertArgumentNotNull(sParaTemp, "sParaTemp");
    AlipayClient client = createAlipayClient();
    AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();
    alipayRequest.setNotifyUrl(alipayConfig.getPayNotify());
    // 待请求参数数组
    sParaTemp.put("seller_id", alipayConfig.getSellerId());
    alipayRequest.setBizContent(JsonUtil.objectToJson(sParaTemp));
    String form = "";
    try {
      form = client.sdkExecute(alipayRequest).getBody();
    } catch (AlipayApiException e) {
      throw new ThorServiceException("支付宝凭证生成失败");
    }
    logger.debug("支付宝支付表单构造:" + form);
    return form;
  }

  private AlipayClient createAlipayClient() {
    AlipayClient client = new DefaultAlipayClient(alipayConfig.getGateWay(),
        alipayConfig.getAppId(), alipayConfig.getAppPrivateKey(), alipayConfig.getPARAM_TYPE(),
        alipayConfig.getCHARSET(), alipayConfig.getAlipayPublicKey(), alipayConfig.getSignType());
    return client;
  }

  @Override
  public boolean callBack(String request) {
    List<NameValuePair> pairs = URLEncodedUtils.parse(request, Charset.forName("UTF-8"));
    Map<String, String> paranMap = new HashMap<String, String>();
    for (NameValuePair pair : pairs) {
      paranMap.put(pair.getName(), pair.getValue());
    }
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    logger.info("支付宝回调参数:" + paranMap.toString());
    EleChargesBill bill = eleChargesBillDao.getByBillNumber(paranMap.get("out_trade_no"));
//    if (bill.getState().equals(EleChargesBillState.PAID)) {
//      return true;
//    }
    if (bill.getNotifyFlag()!=null && bill.getNotifyFlag().equals(this.NOTIFY_FLAG_SUCCESS)) {
      return true;
    }
    
    boolean isVerify = false;
    if (AliPayConfig.SUCCESS_REQUEST.equals(paranMap.get("trade_status"))
        || AliPayConfig.TRADE_CLOSED.equals(paranMap.get("trade_status"))) {
      try {
        isVerify = AlipaySignature
            .rsaCheckV1(paranMap, alipayConfig.getAlipayPublicKey(),
            alipayConfig.getCHARSET());
      } catch (AlipayApiException e) {
        logger.info("支付宝发生错误:" + e.getMessage());
        e.printStackTrace();
      }
    }
    // 调用SDK验证签名
    if (isVerify && AliPayConfig.SUCCESS_REQUEST.equals(paranMap.get("trade_status"))) {
      logger.info("支付成功改变充值单的状态:" + paranMap.toString());
      if (bill != null) {
        bill.setState(EleChargesBillState.PAID); 
        bill.setNotifyFlag(NOTIFY_FLAG_SUCCESS); // 回调使用单独的标志字段
        try {
          bill.setActionTime(dateFormat.parse(paranMap.get("gmt_create")));
        } catch (ParseException e) {
          e.printStackTrace();
        }
        bill.setBuyerLogonId(paranMap.get("buyer_logon_id"));
        bill.setBuyerPayAmount(new BigDecimal(paranMap.get("buyer_pay_amount")));
        bill.setInvoiceAmount(new BigDecimal(paranMap.get("invoice_amount")));
        bill.setReceiptAmount(new BigDecimal(paranMap.get("receipt_amount")));
        bill.setSellerEmail(paranMap.get("seller_email"));
        bill.setTransactioNo(paranMap.get("trade_no"));
        PEleChargesBill billTOSave = EleChargesBillConverter.getInstance().convert(bill);
        eleChargesBillDao.saveEleChargesBill(billTOSave, tool.getOperateInfo());
      }
      return true;
    } else {
      logger.info("验证签名失败:" + paranMap.toString());
      bill.setErrMsg(paranMap.get("trade_status"));
      bill.setNotifyFlag(NOTIFY_FLAG_FAILED);
      PEleChargesBill billTOSave = EleChargesBillConverter.getInstance().convert(bill);
      eleChargesBillDao.saveEleChargesBill(billTOSave, tool.getOperateInfo());
      return isVerify;
    }
  }

 
}
